package com.canaan.business.service.basic.impl;

import com.github.pagehelper.util.StringUtil;
import com.canaan.business.common.enums.storehouse.StoreHouseTypeEnum;
import com.canaan.business.domain.basic.WmsBaseFactory;
import com.canaan.business.domain.basic.WmsStorehouse;
import com.canaan.business.domain.basic.WmsStorehouseArea;
import com.canaan.business.domain.inOutStock.StorehouseStockCheck;
import com.canaan.business.domain.storehouse.WmsStorehouseStock;
import com.canaan.business.mapper.basic.WmsStorehouseMapper;
import com.canaan.business.service.basic.IWmsBaseFactoryService;
import com.canaan.business.service.basic.IWmsStorehouseAreaService;
import com.canaan.business.service.basic.IWmsStorehouseService;
import com.canaan.business.service.inOutStock.IStorehouseStockCheckService;
import com.canaan.business.service.storehouse.IWmsStorehouseStockService;
import com.canaan.common.exception.ServiceException;
import com.canaan.common.utils.DateUtils;
import com.canaan.common.utils.SecurityUtils;
import com.canaan.common.utils.StringUtils;
import org.apache.commons.compress.utils.Lists;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 仓库Service业务层处理
 *
 * @author ruoyi
 * @date 2022-11-29
 */
@Service
public class WmsStorehouseServiceImpl implements IWmsStorehouseService {
    @Resource
    private WmsStorehouseMapper wmsStorehouseMapper;

    @Resource
    private IWmsStorehouseAreaService wmsStorehouseAreaService;

    @Resource
    private IWmsBaseFactoryService wmsBaseFactoryService;

    @Resource
    private IStorehouseStockCheckService storehouseStockCheckService;

    @Resource
    private IWmsStorehouseStockService wmsStorehouseStockService;

    /**
     * 查询仓库
     *
     * @param id 仓库主键
     * @return 仓库
     */
    @Override
    public WmsStorehouse selectWmsStorehouseById(Long id) {
        return wmsStorehouseMapper.selectWmsStorehouseById(id);
    }

    /**
     * 查询仓库列表
     *
     * @param wmsStorehouse 仓库
     * @return 仓库
     */
    @Override
    public List<WmsStorehouse> selectWmsStorehouseList(WmsStorehouse wmsStorehouse) {
        return wmsStorehouseMapper.selectWmsStorehouseList(wmsStorehouse);
    }

    /**
     * 新增仓库
     *
     * @param entity 仓库
     * @return 结果
     */
    @Override
    public WmsStorehouse insertWmsStorehouse(WmsStorehouse entity) {
        if (entity == null || entity.getNo() == null) {
            throw new ServiceException("缺少库区编号");
        } else if (entity.getName() == null) {
            throw new ServiceException("缺少库区名称");
        } else if (StringUtils.isEmpty(entity.getFactoryNo())) {
            throw new ServiceException("缺少厂区数据");
        }
//        List<String> nos = Collections.singletonList(entity.getNo());
//        List<String> names = Collections.singletonList(entity.getName());
        List<String> nos = new ArrayList<String>() {{
            add(entity.getNo());
        }};
        List<String> names = new ArrayList<String>() {{
            add(entity.getName());
        }};
        List<WmsStorehouse> repeatList = wmsStorehouseMapper.listByNoOrName(nos, names);
        if (!repeatList.isEmpty()) {
            //有重复的数据
            WmsStorehouse old = repeatList.stream()
                    .filter(e -> e.getNo().equals(entity.getNo())).findFirst().orElse(null);
            throw new ServiceException(old != null ? "仓库编号已存在" : "仓库名称已存在");
        }

        entity.setCreateBy(SecurityUtils.getUsername());
        entity.setCreateTime(DateUtils.getNowDate());
        wmsStorehouseMapper.insertWmsStorehouse(entity);
        return entity;
    }

    /**
     * 修改仓库
     *
     * @param entity 仓库
     * @return 结果
     */
    @Override
    public int updateWmsStorehouse(WmsStorehouse entity) {
        //校验仓库名称
        List<String> names = Collections.singletonList(entity.getName());
        List<WmsStorehouse> repeatList = wmsStorehouseMapper.listByNoOrName(null, names);
        repeatList = repeatList.stream().filter(e -> !e.getId().equals(entity.getId())).collect(Collectors.toList());
        if (!repeatList.isEmpty()) {
            //有重复的数据
            throw new ServiceException("仓库名称已存在");
        }

        entity.setUpdateBy(SecurityUtils.getUsername());
        entity.setUpdateTime(DateUtils.getNowDate());
        return wmsStorehouseMapper.updateWmsStorehouse(entity);
    }

    /**
     * 批量删除仓库
     *
     * @param ids 需要删除的仓库主键
     * @return 结果
     */
    @Override
    public int deleteWmsStorehouseByIds(Long[] ids) {
        List<WmsStorehouse> list = wmsStorehouseMapper.listByIds(Arrays.asList(ids));
        if (!list.isEmpty()) {
            List<String> nos = list.stream().map(WmsStorehouse::getNo).collect(Collectors.toList());
            List<WmsStorehouseArea> areaList = wmsStorehouseAreaService.listByStorehouseNos(nos);
            if (!areaList.isEmpty()) {
                throw new ServiceException("仓库下还存在库区，请先清除库区");
            }
        }

        return wmsStorehouseMapper.deleteWmsStorehouseByIds(ids);
    }

    /**
     * 删除仓库信息
     *
     * @param id 仓库主键
     * @return 结果
     */
    @Override
    public int deleteWmsStorehouseById(Long id) {
        return wmsStorehouseMapper.deleteWmsStorehouseById(id);
    }

    /**
     * 根据编号或名称查询出列表
     *
     * @param nos   编号列表
     * @param names 名称列表
     * @return 数据列表
     */
    @Override
    public List<WmsStorehouse> listByNoOrName(List<String> nos, List<String> names) {
        return wmsStorehouseMapper.listByNoOrName(nos, names);
    }

    /**
     * 导入数据
     *
     * @param list 导入数据列表
     * @return 错误列表
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<String> importExcel(List<WmsStorehouse> list) {
        List<String> errorList = new ArrayList<>();
        if (StringUtils.isEmpty(list)) {
            return errorList;
        }

        List<String> nos = list.stream().filter(e -> e.getNo() != null).map(WmsStorehouse::getNo).collect(Collectors.toList());
        List<String> names = list.stream().filter(e -> e.getName() != null).map(WmsStorehouse::getName).collect(Collectors.toList());
        List<String> factorys = list.stream().filter(e -> e.getFactoryNo() != null).map(WmsStorehouse::getFactoryNo).collect(Collectors.toList());

        //获取重复的数据
        List<WmsStorehouse> oldList = listByNoOrName(nos, names);
        nos = oldList.stream().map(WmsStorehouse::getNo).collect(Collectors.toList());
        names = oldList.stream().map(WmsStorehouse::getName).collect(Collectors.toList());

        WmsBaseFactory factory = new WmsBaseFactory();
        factory.setNos(factorys);
        List<WmsBaseFactory> factoryList = wmsBaseFactoryService.selectWmsBaseFactoryList(factory);
        List<String> factoryNos = factoryList.stream().filter(a -> a.getNo() != null).map(WmsBaseFactory::getNo).collect(Collectors.toList());

        //行数据校验
        List<String> YNList = Arrays.asList("Y", "N");
        for (int i = 0; i < list.size(); i++) {
            WmsStorehouse entity = list.get(i);

            if (StringUtils.isEmpty(entity.getNo())) {
                errorList.add("第" + (i + 1) + "行缺少仓库编号");
            } else if (nos.contains(entity.getNo())) {
                errorList.add("第" + (i + 1) + "行仓库编号已存在");
            }

            if (StringUtils.isEmpty(entity.getName())) {
                errorList.add("第" + (i + 1) + "行缺少仓库名称");
            } else if (names.contains(entity.getName())) {
                errorList.add("第" + (i + 1) + "行仓库名称已存在");
            }

            if (StringUtils.isEmpty(entity.getTypeNo())) {
                errorList.add("第" + (i + 1) + "行缺少仓库类型或不在选择范围之内");
            }

            if (StringUtils.isEmpty(entity.getFactoryNo())) {
                errorList.add("第" + (i + 1) + "行缺少工厂代码数据");
            } else if (!factoryNos.contains(entity.getFactoryNo())) {
                errorList.add("第" + (i + 1) + "行工厂代码不存在");
            }

            if (StringUtils.isEmpty(entity.getIsLine()) || !YNList.contains(entity.getIsLine())) {
                entity.setIsLine("N");
            }
            if (StringUtils.isEmpty(entity.getIsVirtual()) || !YNList.contains(entity.getIsLine())) {
                entity.setIsVirtual("N");
            }
            if (StringUtils.isEmpty(entity.getStatus())) {
                entity.setStatus("0");
            }
        }

        if (errorList.size() > 0) {
            return errorList;
        }
        //没有什么问题就保存数据
        String username = SecurityUtils.getUsername();
        Date createTime = new Date();
        for (WmsStorehouse wmsStorehouse : list) {
            wmsStorehouse.setCreateBy(username);
            wmsStorehouse.setCreateTime(createTime);
            wmsStorehouseMapper.insertWmsStorehouse(wmsStorehouse);
        }

        return errorList;
    }

    @Override
    public WmsStorehouse selectWmsStorehouseByName(String storehouseName) {
        return wmsStorehouseMapper.selectWmsStorehouseByName(storehouseName);
    }

    @Override
    public WmsStorehouse selectWmsStorehouseByNo(String storehouseNo) {
        return wmsStorehouseMapper.selectWmsStorehouseByNo(storehouseNo);
    }

    @Override
    public List<WmsStorehouse> selectionList(WmsStorehouse wmsStorehouse) {
        List<WmsStorehouse> storehouses = wmsStorehouseMapper.selectWmsStorehouseList(wmsStorehouse);
        return storehouses.stream().filter(a -> !(StoreHouseTypeEnum.DJC.getCode().equals(a.getTypeNo()) || "NC".equals(a.getTypeNo()))).collect(Collectors.toList());
    }

    @Override
    public List<WmsStorehouse> selectByFactory(String factoryNo) {
        WmsStorehouse query = new WmsStorehouse();
        query.setFactoryNo(factoryNo);
        return this.wmsStorehouseMapper.selectWmsStorehouseList(query);
    }

    @Override
    public List<WmsStorehouse> listByProductNo(String productNo, String storehouseType) {
        List<String> storehouseNos = Lists.newArrayList();
        if (StringUtils.isNotEmpty(storehouseType)) {
            if (storehouseType.equals(StoreHouseTypeEnum.DJC.getCode())) {
                WmsStorehouseStock stock = new WmsStorehouseStock();
                stock.setProductNo(productNo);
                List<WmsStorehouseStock> stocks = wmsStorehouseStockService.selectWmsStorehouseStockList(stock);
                storehouseNos.addAll(stocks.stream().map(WmsStorehouseStock::getStorehouseNo).distinct().collect(Collectors.toList()));
            } else if (storehouseType.equals(StoreHouseTypeEnum.LINE_PRODUCT.getCode())) {
                StorehouseStockCheck check = new StorehouseStockCheck();
                check.setProductNo(productNo);
                List<StorehouseStockCheck> checks = storehouseStockCheckService.selectStorehouseStockCheckList(check);
                storehouseNos.addAll(checks.stream().map(StorehouseStockCheck::getStorehouseNo).distinct().collect(Collectors.toList()));
            }
        } else {
            WmsStorehouseStock stock = new WmsStorehouseStock();
            stock.setProductNo(productNo);
            List<WmsStorehouseStock> stocks = wmsStorehouseStockService.selectWmsStorehouseStockList(stock);
            storehouseNos = stocks.stream().map(WmsStorehouseStock::getStorehouseNo).distinct().collect(Collectors.toList());
            StorehouseStockCheck check = new StorehouseStockCheck();
            check.setProductNo(productNo);
            List<StorehouseStockCheck> checks = storehouseStockCheckService.selectStorehouseStockCheckList(check);
            storehouseNos.addAll(checks.stream().map(StorehouseStockCheck::getStorehouseNo).distinct().collect(Collectors.toList()));

        }
        return wmsStorehouseMapper.listByNoOrName(storehouseNos, null);
    }
}
